#include <Timer.h>
#include "printf.h"

typedef nx_struct flashLogEntry_t 
	{
    	nx_uint16_t timeStamp;
    	nx_uint16_t temperature;
    	nx_uint8_t nodeID;
    	nx_uint8_t sentStatus;
  	} flashLogEntry_t;


module EasyDisseminationC {
	uses interface Boot;
	uses interface SplitControl as RadioControl;
	uses interface StdControl as DisseminationControl;
	uses interface DisseminationValue<flashLogEntry_t> as Value;
	
    //uses interface DisseminationValue<uint16_t> as Value;
	
    uses interface DisseminationUpdate<flashLogEntry_t> as Update;
	
    //uses interface DisseminationUpdate<uint16_t> as Update;
	
    uses interface Leds;
	uses interface Timer<TMilli> as Timer1;
	uses interface Timer<TMilli> as TimerDiss;
}

implementation {

    /* Data logging variables */
	    flashLogEntry_t m_localEntry;
    
    void WakeUp();
    void GoToSleep();
    bool mModuleSleeping;	
    uint16_t counter;
    /**
     * To go to sleep, turn off AMControl
     */
    void GoToSleep()
    {
    	printf("Node with id = %d going to sleep\n",m_localEntry.nodeID);
        printfflush();
    	mModuleSleeping = TRUE;
        call DisseminationControl.stop();
    	call RadioControl.stop();
    }
    /**
     * When we wake up, turn on AMControl
     */
    void WakeUp()
    {
    	printf("Node with id = %d woken up\n",m_localEntry.nodeID);
        printfflush();
        mModuleSleeping = FALSE;
    	call RadioControl.start();	
    }
	task void ShowCounter() {
    	counter = m_localEntry.temperature;
		if(counter & 0x01) call Leds.led0On(); else call Leds.led0Off();
		if(counter &0x02) call Leds.led1On(); else call Leds.led1Off();
		if(counter & 0x04) call Leds.led2On(); else call Leds.led2Off();
	}
	event void Boot.booted() {
		//call RadioControl.start();
        call Timer1.startPeriodic(2000);
        m_localEntry.temperature=4;
		m_localEntry.nodeID=4;
	}

    event void Timer1.fired() {
        WakeUp();
    }
	event void RadioControl.startDone(error_t err) {
		if(err != SUCCESS) {
            call RadioControl.start();
            printf("RadioControlStart failed\n");
            printfflush();
        }
		else {
			call DisseminationControl.start();
            
            printf("Node with id = %d started Radio\n",m_localEntry.nodeID); 
            printfflush();
			call TimerDiss.startOneShot(2000);
            
        }
	}
    event void TimerDiss.fired() {
    /* Code for disseminating node */
        printf("Node with id = %d sending update\n",m_localEntry.nodeID); 
		m_localEntry.temperature = m_localEntry.temperature + 4;
		//post ShowCounter();
		call Update.change(&m_localEntry);
		GoToSleep();
	/* End of code for disseminating node */

    } 
	event void RadioControl.stopDone(error_t err) {}
	event void Value.changed() {
		const flashLogEntry_t *new_value = call Value.get();
		//const uint16_t *new_value = call Value.get();
		post ShowCounter();
        printf("Non-root-node with ID = %d seeing value changed = %d\n", (new_value)->nodeID, (new_value)->temperature);
		printfflush();
	}
}
